package cn.gok.controller;

import cn.gok.util.ResponseUtil;
import cn.gok.util.ResultData;
import cn.hutool.json.JSONUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Description: 做文件上传测试的Servlet
 * @Author: chen fan
 * @Date: 2022年10月21日 10:24:54
 */
@WebServlet("/fileUpTest")
public class TestFileUpServlet extends HttpServlet {

    private static String urls;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        switch (action){
            case "fileUp":fileUp(req,resp);break;
            case "showImage":showImage(req,resp);break;

        }

    }

    private void showImage(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        List<String> imageUrls = JSONUtil.toList(urls, String.class);
        ResponseUtil.send(resp, ResultData.createData(10001, imageUrls));
    }


    private void fileUp(HttpServletRequest req,
                          HttpServletResponse resp) throws ServletException, IOException {
        //构建文件上传的工厂对象
        FileItemFactory fileItemFactory = new DiskFileItemFactory();
        //构建文件上传对象
        ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

        /*
           文件上传操作中，我们最核心的就是要去获取  FileItem对象
            前端提交每个input 都存放在一个FileItem对象中

            注： 前端的提交的数据，并不是说所有input都是  文件，
                它也可能是文本数据，我们可以通过FileItem提供的方法
                来判断当前FileItem对象是什么样的数据，然后进行最终的处理。
         */
        Map<String, List<FileItem>> parameterMap = null;


        //存存放多个图片的文件名，最终会将该数组转成json字符串，存入数据库
        List<String> imageNames =  new ArrayList<>();

        try {
            parameterMap = servletFileUpload.parseParameterMap(req);

            //拿到图片文件，然后将写出到本地的某个文件夹中，实现文件上传操作
            List<FileItem> images = parameterMap.get("image");
            for (FileItem fileItem : images){

                /*
                    在本地创建一个文件夹，用存放上传的图片
                    在上传对的时候我们还需要对图片的文件名进行重新生成（比如可以使用UUID生成不重复的字符串）
                 */
                //获取原始的文件名
                String fileName = fileItem.getName();
                //获取图片的后缀名 比如  .png 、.jpg
                String suffixName = fileName.substring( fileName.lastIndexOf("."));
                //通过uuid生成一个永不重复的字符串，和后缀名拼接成新的文件名
                String newFileName = UUID.randomUUID().toString() + suffixName;

                imageNames.add(newFileName);

                //创建文件夹以及File对象
                //req.getServletContext().getRealPath("") 获取当前项目所在的路径
                String filePath = req.getServletContext().getRealPath("") + File.separator + "images";
                File file = new File(filePath);
                if (!file.exists()){
                    file.mkdir();
                }
                //将图片文件写出到指定的位置
                fileItem.write(new File( filePath + File.separator + newFileName));
            }
        } catch (FileUploadException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        urls = JSONUtil.toJsonStr(imageNames);
        List<FileItem> descFileItem = parameterMap.get("desc");
        String desc = new String(descFileItem.get(0).get(), "utf-8");

        System.out.println( "imageUrl: " + urls);
        System.out.println("desc: " + desc);

        //上传成功，则立即跳转图片显示页
        resp.sendRedirect("fileUpImageShowTest.html");

    }
}
